package com.ygqh.baby.service.weixin.templatemessage;

import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.log4j.Logger;
import org.crazycake.shiro.SerializeUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.NameFilter;
import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.http.weixin.JsonResult;
import com.foxinmy.weixin4j.http.weixin.WeixinRequestExecutor;
import com.foxinmy.weixin4j.http.weixin.WeixinResponse;
import com.foxinmy.weixin4j.model.Token;
import com.foxinmy.weixin4j.model.WeixinAccount;
import com.foxinmy.weixin4j.mp.message.TemplateMessage;
import com.foxinmy.weixin4j.mp.model.TemplateMessageInfo;
import com.foxinmy.weixin4j.token.TokenHolder;
import com.foxinmy.weixin4j.util.NameValue;
import com.foxinmy.weixin4j.util.StringUtil;
import com.ygqh.baby.ao.Message;
import com.ygqh.baby.ao.WxMessageType;
import com.ygqh.baby.redis.RedisDao;
import com.ygqh.baby.service.wechat.api.YgTmplApi;
import com.ygqh.baby.service.wechat.message.YgSubscribeTempMsg;
import com.ygqh.baby.service.weixin.model.SmallTemplateMessage;
import com.ygqh.baby.service.weixin.token.WxTokenManager;

@Component
public class SmallTemplateMessageApi extends TemplateMessageApi {
	protected final Logger logger = Logger.getLogger(this.getClass());
	@Autowired
	private WxTokenManager wxTokenManager;
	@Autowired
	private RedisDao redisDao;

	WeixinRequestExecutor weixinExecutor = new WeixinRequestExecutor();

	@Override
	public <T extends TemplateMessage> Message sendTemplateMessage(T t, String appId, String appSecret) {

		try {
			JsonResult sendResult = sendMessage(t, appId, appSecret);
			if (sendResult.getCode() == 0) {
				return Message.success(sendResult.getText(), null);
			}

			return Message.error(sendResult.toString(), null);
		} catch (WeixinException e) {
			logger.warn("发送小程序模板消息失败；openId=【" + t.getToUser() + "】【" + t.getHead() + "】" + e.getMessage());
			e.printStackTrace();
			Message.error(e.getMessage());
		}
		return Message.success(null);

	}

	@Override
	public <T extends TemplateMessage> Message sendTemplateMessage(T t, WeixinAccount weixinAccount) {

		return this.sendTemplateMessage(t, weixinAccount.getId(), weixinAccount.getSecret());
	}

	private <T extends TemplateMessage> JsonResult sendMessage(T t, String appId, String appSecret) throws WeixinException {
		TokenHolder tokenHolder = wxTokenManager.getTokenHolder(appId, appSecret);
		Token token = tokenHolder.getToken();
		String template_send_uri = "https://api.weixin.qq.com/cgi-bin/message/wxopen/template/send?access_token=%s";
		WeixinResponse response = weixinExecutor.post(String.format(template_send_uri, token.getAccessToken()), JSON.toJSONString(t, new NameFilter() {
			@Override
			public String process(Object object, String name, Object value) {
				if (object instanceof NameValue && name.equals("name")) {
					return "color";
				}
				return name;
			}
		}));

		return response.getAsJsonResult();

	}

	@Override
	public List<TemplateMessageInfo> getTemplateMessageList(WeixinAccount weixinAccount) {
		YgTmplApi api = new YgTmplApi(wxTokenManager.getTokenHolder(weixinAccount));

		return api.getSmallAllTmplateMsg();

	}

	@Override
	public String getTemplateMessageId(WxMessageType wxMessageType, WeixinAccount weixinAccount) {

		String key = String.format("wx_tempid_%s", weixinAccount.getId() + "_" + wxMessageType.name());
		String msgTmpId = (String) SerializeUtils.deserialize(redisDao.get(key.getBytes()));
		if (StringUtil.isEmpty(msgTmpId)) {

			List<TemplateMessageInfo> list = this.getTemplateMessageList(weixinAccount);
			for (TemplateMessageInfo msg : list) {
				if (wxMessageType.getTitle().equals(msg.getTitle())) {
					redisDao.set(key.getBytes(), SerializeUtils.serialize(msg.getTemplateId()));
					return msg.getTemplateId();
				}
			}
		}
		return msgTmpId;
	}

	/**
	 * 发送一次性订阅消息
	 * 
	 * @Title: sendTmplMessage
	 * @param tplMessage
	 * @throws WeixinException
	 *             入参
	 * @return JsonResult 返回类型
	 * @author （guohao）
	 * @throws
	 * @date 2017年9月8日 上午10:32:53
	 * @version V1.0
	 */
	public JsonResult sendTmplMessage(YgSubscribeTempMsg tplMessage, String appId, String appSecret) throws WeixinException {
		Token token = wxTokenManager.getToken(appId, appSecret);
		String template_send_uri = "https://api.weixin.qq.com/cgi-bin/message/template/subscribe?access_token=%s";
		WeixinResponse response = weixinExecutor.post(String.format(template_send_uri, token.getAccessToken()), JSON.toJSONString(tplMessage, new NameFilter() {
			@Override
			public String process(Object object, String name, Object value) {
				if (object instanceof NameValue && name.equals("name")) {
					return "color";
				}
				return name;
			}
		}));

		return response.getAsJsonResult();
	}

	public TemplateMessage assemblyTemplateMessage(WxMessageType wxMessageType, WeixinAccount weixinAccount, String openId, String url, String formId,
			String emphasisKeyword, Map<String, NameValue> contentMap) {

		this.getTemplateMessageId(wxMessageType, weixinAccount);
		String wxMsgTempId = this.getTemplateMessageId(wxMessageType, weixinAccount);
		TemplateMessage tplMessage = new SmallTemplateMessage(openId, wxMsgTempId, "", url, formId, emphasisKeyword);
		for (Entry<String, NameValue> entry : contentMap.entrySet()) {
			String color = StringUtil.isBlank(entry.getValue().getName()) ? "#323232" : entry.getValue().getName();
			if (entry.getKey().equals("first")) {
				tplMessage.pushHead(color, entry.getValue().getValue());
			}
			tplMessage.pushItem(entry.getKey(), color, entry.getValue().getValue());
		}

		return tplMessage;
	}
	@Override
	public TemplateMessage assemblyTemplateMessage(WxMessageType wxMessageType, WeixinAccount weixinAccount, String openId, String url, String formId,
			String emphasisKeyword, String... keyword) {

		String wxMsgTempId = this.getTemplateMessageId(wxMessageType, weixinAccount);
		TemplateMessage tplMessage = new SmallTemplateMessage(openId, wxMsgTempId, "", url, formId, emphasisKeyword);
		for (int i = 0; i < keyword.length; i++) {
			tplMessage.pushItem("keyword" + (i + 1), "#323232", keyword[i]);
		}
		return tplMessage;

	}

	@Deprecated
	@Override
	public TemplateMessage assemblyTemplateMessage(WxMessageType wxMessageType, WeixinAccount weixinAccount, String openId, String url,
			Map<String, NameValue> contentMap) {
		return null;
	}
}
